/**
 * 全局错误处理器
 * 处理未被React错误边界捕获的错误，如异步错误、Promise rejection等
 */
export class GlobalErrorHandler {
  private static instance: GlobalErrorHandler;
  private isInitialized = false;

  static getInstance(): GlobalErrorHandler {
    if (!GlobalErrorHandler.instance) {
      GlobalErrorHandler.instance = new GlobalErrorHandler();
    }
    return GlobalErrorHandler.instance;
  }

  /**
   * 初始化全局错误处理
   */
  initialize(): void {
    if (this.isInitialized) {
      return;
    }

    // 捕获未处理的JavaScript错误
    window.addEventListener('error', this.handleGlobalError.bind(this));

    // 捕获未处理的Promise rejection
    window.addEventListener('unhandledrejection', this.handlePromiseRejection.bind(this));

    // 捕获资源加载错误
    window.addEventListener('error', this.handleResourceError.bind(this), true);

    this.isInitialized = true;
    console.log('✅ Global Error Handler initialized');
  }

  /**
   * 销毁全局错误处理器
   */
  destroy(): void {
    if (!this.isInitialized) {
      return;
    }

    window.removeEventListener('error', this.handleGlobalError.bind(this));
    window.removeEventListener('unhandledrejection', this.handlePromiseRejection.bind(this));
    window.removeEventListener('error', this.handleResourceError.bind(this), true);

    this.isInitialized = false;
    console.log('🧹 Global Error Handler destroyed');
  }

  /**
   * 处理全局JavaScript错误
   */
  private handleGlobalError(event: ErrorEvent): void {
    const error = event.error || new Error(event.message);
    const errorInfo = {
      id: this.generateErrorId(),
      type: 'GlobalError',
      message: event.message,
      filename: event.filename,
      lineno: event.lineno,
      colno: event.colno,
      stack: error.stack,
      timestamp: Date.now(),
      url: window.location.href,
      userAgent: navigator.userAgent
    };

    this.reportError(errorInfo);
  }

  /**
   * 处理未捕获的Promise rejection
   */
  private handlePromiseRejection(event: PromiseRejectionEvent): void {
    const error = event.reason instanceof Error ? event.reason : new Error(String(event.reason));
    const errorInfo = {
      id: this.generateErrorId(),
      type: 'UnhandledPromiseRejection',
      message: error.message || 'Unhandled Promise Rejection',
      stack: error.stack,
      reason: event.reason,
      timestamp: Date.now(),
      url: window.location.href,
      userAgent: navigator.userAgent
    };

    this.reportError(errorInfo);

    // 防止错误显示在控制台（可选）
    event.preventDefault();
  }

  /**
   * 处理资源加载错误
   */
  private handleResourceError(event: Event): void {
    const target = event.target as HTMLElement;
    
    // 只处理资源加载错误，不处理JavaScript错误
    if (target && target !== (window as any) && (
      target.tagName === 'IMG' ||
      target.tagName === 'SCRIPT' ||
      target.tagName === 'LINK' ||
      target.tagName === 'VIDEO' ||
      target.tagName === 'AUDIO'
    )) {
      const errorInfo = {
        id: this.generateErrorId(),
        type: 'ResourceError',
        message: `Failed to load ${target.tagName.toLowerCase()}`,
        element: target.tagName,
        src: (target as any).src || (target as any).href,
        timestamp: Date.now(),
        url: window.location.href,
        userAgent: navigator.userAgent
      };

      this.reportError(errorInfo);
    }
  }

  /**
   * 生成错误ID
   */
  private generateErrorId(): string {
    return `GLOBAL_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }

  /**
   * 报告错误
   */
  private reportError(errorInfo: any): void {
    // 记录到控制台
    console.group(`🚨 Global Error - ${errorInfo.id}`);
    console.error('Type:', errorInfo.type);
    console.error('Message:', errorInfo.message);
    if (errorInfo.stack) {
      console.error('Stack:', errorInfo.stack);
    }
    console.error('Full Error Info:', errorInfo);
    console.groupEnd();

    // 存储到本地
    this.storeErrorLocally(errorInfo);

    // 发送到background script
    this.sendToBackground(errorInfo);
  }

  /**
   * 将错误存储到本地
   */
  private storeErrorLocally(errorInfo: any): void {
    try {
      const existingErrors = JSON.parse(
        localStorage.getItem('extension-global-errors') || '[]'
      );
      
      // 保留最近的15个错误
      const updatedErrors = [errorInfo, ...existingErrors].slice(0, 15);
      
      localStorage.setItem('extension-global-errors', JSON.stringify(updatedErrors));
    } catch (e) {
      console.warn('Failed to store error locally:', e);
    }
  }

  /**
   * 发送错误到background script
   */
  private sendToBackground(errorInfo: any): void {
    try {
      if (typeof chrome !== 'undefined' && chrome.runtime) {
        chrome.runtime.sendMessage({
          type: 'GLOBAL_ERROR_REPORT',
          payload: errorInfo
        }).catch(() => {
          // 忽略发送失败
        });
      }
    } catch (e) {
      // 忽略Chrome API错误
    }
  }

  /**
   * 手动报告错误
   */
  static reportError(error: Error, context?: string): void {
    const instance = GlobalErrorHandler.getInstance();
    const errorInfo = {
      id: instance.generateErrorId(),
      type: 'ManualReport',
      message: error.message,
      stack: error.stack,
      context: context || 'Manual Report',
      timestamp: Date.now(),
      url: window.location.href,
      userAgent: navigator.userAgent
    };

    instance.reportError(errorInfo);
  }

  /**
   * 获取本地存储的错误
   */
  static getLocalErrors(): any[] {
    try {
      return JSON.parse(localStorage.getItem('extension-global-errors') || '[]');
    } catch (e) {
      console.warn('Failed to get local errors:', e);
      return [];
    }
  }

  /**
   * 清除本地存储的错误
   */
  static clearLocalErrors(): void {
    try {
      localStorage.removeItem('extension-global-errors');
    } catch (e) {
      console.warn('Failed to clear local errors:', e);
    }
  }
}

// 自动初始化（可选）
let globalErrorHandler: GlobalErrorHandler;

/**
 * 初始化全局错误处理
 */
export function initGlobalErrorHandler(): void {
  if (!globalErrorHandler) {
    globalErrorHandler = GlobalErrorHandler.getInstance();
    globalErrorHandler.initialize();
  }
}

/**
 * 销毁全局错误处理
 */
export function destroyGlobalErrorHandler(): void {
  if (globalErrorHandler) {
    globalErrorHandler.destroy();
    globalErrorHandler = undefined as any;
  }
}

export default GlobalErrorHandler;